﻿using System;

namespace Glue.Internals
{
    internal partial class ObjectMemberFactory
    {
        private abstract class CollectionMemberBase : ObjectMember, ICollectionMember
        {
            private bool passSpecialMappableCollections = false;
            protected CollectionMemberBase(IObjectMemberAccessor accessor):base(accessor) {}

            public abstract IGlueCollection CreateCollection(IGlueCollection collection);
            public abstract Type GetElementType();

            public bool IsPrimitive()
            {
                return GetElementType().IsPrimitive();
            }

            public bool IsNested()
            {
                return !IsPrimitive();
            }

            public override object InvokeGet(object toInvokeOn)
            {
                if (passSpecialMappableCollections)
                    return InvokeSpecialGet(toInvokeOn);
                return InvokeGetOnActualObject(toInvokeOn);
            }

            protected object InvokeGetOnActualObject(object toInvokeOn)
            {
                return base.InvokeGet(toInvokeOn);
            }

            protected abstract object InvokeSpecialGet(object toInvokeOn);
            

            public override void InvokeSet(object toInvokeOn, object toSet)
            {
                if (passSpecialMappableCollections)
                    InvokeSpecialSet(toInvokeOn, toSet);
                else
                    InvokeSetOnActualObject(toInvokeOn,toSet);
            }

            protected void InvokeSetOnActualObject(object toInvokeOn, object toSet)
            {
                base.InvokeSet(toInvokeOn, toSet);
            }

            protected abstract void InvokeSpecialSet(object toInvokeOn, object toSet);

            public void PassSpecialMappableCollections()
            {
                passSpecialMappableCollections = true;
            }
            
        }
    }
}
